package com.idea.relax.boot.file;

import com.idea.relax.tool.core.*;
import lombok.Getter;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Objects;
import java.util.UUID;

/**
 * @author: 沉香
 * @date: 2023/4/19
 * @description: 文件上传增强类
 */
@Getter
public class FileObject {

	/**
	 * 文件ID
	 */
	private final Object fileId;

	/**
	 * 文件名称
	 */
	private final String fileName;

	/**
	 * 新文件名称
	 */
	private final String newFileName;

	/**
	 * 后缀
	 */
	private final String ext;

	/**
	 * 大小
	 */
	private final Long size;

	/**
	 * MultipartFile
	 */
	private final MultipartFile file;

	/**
	 * 文件原名
	 */
	private final String originalFileName;

	/**
	 * 上传路径
	 */
	private String uploadDir;

	private static RelaxFileProperties fileProperties;

	private static RelaxFileProperties getFileProperties() {
		if (fileProperties == null) {
			fileProperties = SpringUtil.getBean(RelaxFileProperties.class);
		}
		return fileProperties;
	}


	public FileObject(MultipartFile file) {
		this(FileUtil.getFileId(), file);
	}

	public FileObject(Object fileId, MultipartFile file) {
		this(fileId, FileUtil.getDir(getFileProperties().getParentPath(),
			getFileProperties().getParentPath(), null, file.getOriginalFilename()), file);
	}


	public FileObject(Object fileId, MultipartFile file, String dir) {
		this.fileId = fileId;
		this.file = file;
		this.originalFileName = file.getOriginalFilename();
		this.newFileName = FileUtil.renameToUUID(file.getOriginalFilename());
		this.fileName = file.getName();
		this.size = file.getSize();
		this.ext = FileUtil.getFileExt(file.getName());
		this.uploadDir = FileUtil.getDir(getFileProperties().getParentPath(),
			getFileProperties().getParentPath(), dir, file.getOriginalFilename());
	}


	public FileObject(Object fileId, String uploadDir, MultipartFile file) {
		this.fileId = fileId;
		this.file = file;
		this.originalFileName = file.getOriginalFilename();
		this.newFileName = FileUtil.renameToUUID(file.getOriginalFilename());
		this.fileName = file.getName();
		this.size = file.getSize();
		this.ext = FileUtil.getFileExt(file.getName());
		this.uploadDir = uploadDir;
	}


	public void transfer() {

		if (!uploadDir.endsWith(File.separator)) {
			uploadDir += File.separator;
		}

		File uploadDirFile = new File(uploadDir + newFileName);
		File parentFile = uploadDirFile.getParentFile();
		FileUtil.createDir(parentFile);
		try {
			file.transferTo(uploadDirFile);
		} catch (IOException e) {
			throw ExceptionUtil.unchecked(e);
		}
	}

	public void toZip(OutputStream out) {
		ZipUtils.fileObjectToZip(this, out);
	}

	public void toZip(String output) {
		OutputStream out = null;
		try {
			File file = new File(output);
			File parentFile = file.getParentFile();
			FileUtil.createDir(parentFile);
			out = new FileOutputStream(file);
			ZipUtils.fileObjectToZip(this, out);
		} catch (FileNotFoundException e) {
			throw ExceptionUtil.unchecked(e);
		} finally {
			try {
				if (out != null) {
					out.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public byte[] encrypt(String aesTextKey) throws IOException {
		Assert.notNull(aesTextKey, "aesTextKey不能是空");
		Assert.notNull(file, "读取File对象失败");
		InputStream inputStream = file.getInputStream();
		ByteArrayOutputStream buffer = new ByteArrayOutputStream();
		int len;
		byte[] data = new byte[2 * 1024];
		while ((len = inputStream.read(data, 0, data.length)) != -1) {
			buffer.write(data, 0, len);
		}
		buffer.flush();
		byte[] byteArray = buffer.toByteArray();
		return AesUtil.encrypt(byteArray, aesTextKey);
	}

	public void compress(String output) {
		compress(output, 2.00, false);
	}

	public void compress(String output, double scale, boolean flag) {
		try {
			FileUtil.createDir(output);
			compress(new FileOutputStream(output), scale, flag);
		} catch (Exception e) {
			throw ExceptionUtil.unchecked(e);
		}

	}

	public void compress(OutputStream output, double scale, boolean flag) {
		try {
			BufferedImage bufferedImage = ImageUtil.readImage(Objects.requireNonNull(file, "读取File对象失败").getInputStream());
			if (Func.isEmpty(bufferedImage)) {
				throw new RuntimeException("源文件不是图片或者未读取到资源");
			}
			ImageUtil.zoomScale(bufferedImage, output, null, scale, flag);
		} catch (IOException e) {
			throw ExceptionUtil.unchecked(e);
		}
	}


}
